package rapier.sso.server.handler.impl;

import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import javax.validation.constraints.NotNull;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import rapier.sso.core.config.redis.RedisClient;
import rapier.sso.core.entity.TDbSysUserEntity;
import rapier.sso.core.model.UserModel;
import rapier.sso.server.constant.RapierServerConstant;
import rapier.sso.server.env.RapierSsoServerEnv;
import rapier.sso.server.handler.IAuthHandler;
import rapier.sso.server.handler.IAuthenticationHandler;
import rapier.sso.server.model.Credential;
import rapier.sso.server.utils.TokenUtils;

/**
 *
 */
@Component
public class DefaultAuthenticationHandler implements IAuthenticationHandler {

	@Autowired
	private RedisClient redisClient;
	@Autowired
	private RapierSsoServerEnv ssoServerEnv;

	@Autowired
	private List<IAuthHandler> authHandlers;

	@Override
	public UserModel authenticate(Credential credential) throws Exception {
		try {
			// 从持久化中查询登录账号对应的用户对象
			boolean authResult = false;
			for (IAuthHandler handler : authHandlers) {
				if (handler.support(credential)) {
					authResult = handler.auth(credential);
				} else {
					continue;
				}
				if (!authResult) {// 失败
					return null;// 直接返回
				}
			}
			TDbSysUserEntity entity = credential.getUserEntity();
			for (IAuthHandler handler : authHandlers) {
				if (handler.support(credential)) {
					handler.release(credential);
				}
			}
			if (entity != null) {
				UserModel userModel = new UserModel();
				BeanUtils.copyProperties(entity, userModel);
				return userModel;
			}
			return null;
		} catch (Exception ex) {
			credential.setError("系统异常!");
			return null;
		}
	}

	@Override
	public Set<String> authedSystemIds(UserModel loginUser) throws Exception {
		return null;
	}

	// 自动登录
	@Override
	public UserModel autoLogin(@NotNull String tg) throws Exception {
		String userId = TokenUtils.getUserId(tg);
		Object tgObj = this.redisClient.get(RapierServerConstant.REDIS_SSO_USER_TG_KEY + userId);
		if (tgObj != null && UserModel.class.isInstance(tgObj)) {
			return (UserModel) tgObj;
		}
		return null;
	}

	// 生成自动登录标识
	@Override
	public String loginToken(UserModel userModel) throws Exception {
		// 生成一个唯一标识用作lt
		String tg = TokenUtils.makeToken(userModel.getId(), RapierServerConstant.RAPIER_SSO_SERVER_SECRET);
		redisClient.set(RapierServerConstant.REDIS_SSO_USER_TG_KEY + userModel.getId(), userModel,
				(long) ssoServerEnv.getTokenTGExpireHours(), TimeUnit.HOURS);
		return tg;
	}

	// 更新持久化的lt
	@Override
	public void clearLoginToken(UserModel userModel) throws Exception {
		redisClient.remove(RapierServerConstant.REDIS_SSO_USER_TG_KEY + userModel.getId());
	}
}
